package com.operation.page;

import com.operation.utils.RequestPageUtil;
import java.util.LinkedList;

/**
 * 封装页面置换算法页面
 * 页面置换过程
 * fcfs算法
 * 维持容量为size的队列container，当前每需要访问一个页面
 * 页面在队列，不改变
 * 页面不在队列的时候
 * 大小小于size，从队列尾部插入
 * 否则，将队列头部页面置换成待访问的页面
 * lru算法
 * 维持容量为size的栈，当前每需要访问一个页面
 * 页面在栈中，将该元素提到栈顶
 * 页面不在栈中的时候
 * 大小小于size，插入栈顶
 * 否则，将栈顶尾部页面换出，同时将带访问页面插入栈顶
 * 同时需要计算缺页的次数
 * 实时展示队列（栈中元素的情况）
 */
public class PageReplacement {

    public PageReplacement() {

    }

    private int capacity;//队列和栈的容量
    private LinkedList<Integer> container;//队列或者栈
    private int number;//缺页次数
    private String name;

    public PageReplacement(String name,int capacity) {

        this.name = name;
        this.capacity = capacity;
        this.container = new LinkedList<>();
        this.number = 0;
    }

    /**
     * 实现fcfs算法
     *
     * @param currentPage 当前待访问的页面
     * @return 被替换的页面, 不需要置换时返回-1
     */
    public int fcfs(int currentPage) {
        if (RequestPageUtil.isExists(container,currentPage)) {
            //待访问页在队列中，不做操作
            return -1;
        }
        if (container.size() >= this.capacity) {
            //需要置换
            int result = container.removeFirst();
            container.addLast(currentPage);
            this.number++;//缺页次数增加
            return result;
        }

        //直接插入队尾
        container.addLast(currentPage);
        this.number++;
        return -1;

    }

    /**
     * 实现lru算法
     *
     * @param currentPage 当前待访问的页面
     * @return 被替换的页面, 不需要置换时返回-1
     */
    public int lru(int currentPage) {

        if (RequestPageUtil.isExists(container,currentPage)) {
            this.container.removeIf(ele->ele==currentPage);
            this.container.addFirst(currentPage);
            return -1;
        }
        if (this.container.size() >= this.capacity) {
            int result = container.removeLast();
            this.container.addFirst(currentPage);
            this.number++;//缺页次数增加
            return result;
        }

        this.container.addFirst(currentPage);
        this.number++;
        return -1;
    }

    /**
     * 实时展示队列（栈内页面情况）
     */
    public void display(){

        if(this.container.size()==0){
            System.out.println("为空");
        }else{
            System.out.print("首部");
            this.container.forEach(ele->{
                System.out.print(ele+" ");
            });
            System.out.println("尾部");
        }
    }
    /**
     * 返回缺页次数
     */
    public int getPageFault(){
        return this.number;
    }

}
